﻿using System;
using System.Drawing;
using System.IO;
using SharpZipLib.Zip;
using Tsanie.ShellExt.Definitions;

namespace Tsanie.ShellExt.Thumbnail
{
    public class OszProvider : ThumbnailBaseProvider
    {
        public override string ProviderName { get { return "Thumbnail.Osz"; } }
        public override ProviderType Type { get { return ProviderType.Thumbnail; } }
        public override string[] Exts { get { return new[] { ".osz" }; } }
        public override string Creator { get { return "Tsanie"; } }
        public override string Description { get { return "一个支持osz曲包显示封面缩略图的插件。"; } }

        public override Bitmap GetBitmap(string filename, ThumbnailFlags flags, int colorDepth, Size size)
        {
            return GetBackgroundFromOsz(filename);
        }

        public Bitmap GetBackgroundFromOsz(string filename)
        {
            bool found = false;
            ZipEntry entry;
            string bgFile = null;
            using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                if (stream.Length == 0)
                {
                    Common.OutputDebugString("get_GetImage(void):: Error - file length == 0. {0}", filename);
                    stream.Close();
                    return null;
                }
                try
                {
                    using (ZipInputStream zip = new ZipInputStream(stream))
                    {
                        while (!found && ((entry = zip.GetNextEntry()) != null))
                        {
                            int pos = entry.Name.LastIndexOf('.');
                            if (pos >= 0)
                            {
                                if (entry.Name.Substring(pos).ToLower() == ".osu")
                                {
                                    // 找到.osu文件
                                    if (entry.Size <= 0)
                                    {
                                        Common.OutputDebugString("GetBackgroundFromOsz(Stream):: Warning entry size == 0. {0}", entry.Name);
                                        break;
                                    }
                                    byte[] bs = new byte[entry.Size];
                                    zip.Read(bs, 0, bs.Length);
                                    StreamReader reader = new StreamReader(new MemoryStream(bs));
                                    string line;
                                    bool isTaiko = false;
                                    while ((line = reader.ReadLine()) != null)
                                    {
                                        if (!isTaiko && line.StartsWith("Mode:"))
                                        {
                                            isTaiko = (line.Substring(5).Trim() == "1");
                                        }
                                        else if (!isTaiko && line.StartsWith("0,0,\""))
                                        {
                                            line = line.Substring(5).Trim(new char[] { ' ', '\"' }).ToLower();
                                            if (line.EndsWith(".jpg") || line.EndsWith(".png"))
                                            {
                                                // 找到图片
                                                bgFile = line;
                                                found = true;
                                                break;
                                            }
                                        }
                                    }
                                    reader.Close();
                                    reader = null;
                                    bs = null;
                                }
                            }
                        }
                        zip.Close();
                    }
                }
                catch (Exception e)
                {
                    Common.OutputError(string.Format("GetBackgroundFromOsz('{0}')", filename), e);
                    stream.Close();
                    return null;
                }
            }
            if (!found)
            {
#if DEBUG
                Common.OutputDebugString("GetBackgroundFromOsz(Stream):: Warning '{0}' hasn't a bgFile.", filename);
#endif
                return null;
            }
            using (ZipInputStream zip = new ZipInputStream(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
            {
                Bitmap bmp = null;
                while ((entry = zip.GetNextEntry()) != null)
                {
                    if (entry.Name.Substring(entry.Name.LastIndexOf('/') + 1).ToLower() == bgFile)
                    {
                        // 找到背景图片
                        if (entry.Size <= 0)
                        {
                            Common.OutputDebugString("GetBackgroundFromOsz(Stream).GetImage:: Warning entry size == 0. {0}", entry.Name);
                            break;
                        }
                        byte[] bs = new byte[entry.Size];
                        zip.Read(bs, 0, bs.Length);
                        try
                        {
                            bmp = Bitmap.FromStream(new MemoryStream(bs)) as Bitmap;
                        }
                        catch (Exception e)
                        {
                            Common.OutputDebugString("GetBackgroundFromOsz(Stream).GetImage:: Exception, {0} - {1}", e.GetType().FullName, e.Message);
                        }
                        bs = null;
                    }
                }
                zip.Close();
                return bmp;
            }
        }
    }
}
